package com.zhsource.auth;

import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import com.alibaba.fastjson2.JSONObject;
import com.zhsource.auth.Payload;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Neuronet
 * @Date: 2023-10-05
 * @Description: 针对登录Token的JWT工具类
 * @Version:1.0
 */
public class LoginJwtUtil {

    // JWT所需要的密钥
    private static final byte[] KEY = "Neuronet".getBytes();


    // 设置Token过期时间：30分钟
    public static final long EXPIRE = 30 * 60;

    /**
     * @Description: 根据用户信息生成Token
     * @Author: Neuronet
     * @Date: 2023/10/5 15:53
     * @param payload: 用户信息,包括基本信息、资源权限信息、菜单权限信息
     * @Return: JWT-Token令牌
     **/
    public static String generateTokenForUser(Payload payload) {
        Map<String, Object> map = new HashMap<>();
        map.put("payload", payload);
        return generateToken(map);
    }

    /**
     * @Description: 根据 map 生成 token 默认：HS265(HmacSHA256)算法
     * @Author: Neuronet
     * @Date: 2023/10/5 15:53
     * @param map: 生成Token的信息
     * @Return: JWT-Token令牌
     **/
    public static String generateToken(Map<String, Object> map) {
        // 1.创建JWT对象
        JWT jwt = JWT.create();
        // 2.设置携带数据
        map.forEach(jwt::setPayload);
        // 3.设置密钥
        jwt.setKey(KEY);
        // 4.设置过期时间
        jwt.setExpiresAt(new Date(System.currentTimeMillis() + EXPIRE * 1000));
        return jwt.sign();
    }

    /**
     * @Description: 验证Token是否正确
     * @Author: Neuronet
     * @Date: 2023/10/5 15:54
     * @param token: 要验证的Token
     * @Return: 是否验证通过，false不通过，true通过
     **/
    public static boolean verify(String token) {
        // 1.验证Token是否为空
        if (StrUtil.isBlank(token)) {return false;}
        // 2.验证Token
        return JWT.of(token).setKey(KEY).verify();
    }

    /**
     * @Description: 验证Token是否正确并获取用户信息
     * @Author: Neuronet
     * @Date: 2023/10/5 15:55
     * @param token: 要验证的Token
     * @Return: 用户信息
     **/
    public static Payload verifyAndGetUser(String token) {
        // 1.验证Token是否正确
        if(!verify(token)) {return null;}
        // 2.解析数据
        JWT jwt = JWT.of(token);
        Object payloadObj = jwt.getPayload("payload");
        // 把object对象先转换为字符串，再讲字符串转换为你指定的对象
        // 注意：fastjson的对象转换只能接收json字符串转换为指定对象
        // JWT中的数据就是json格式，所以我们可以直接toString
        Payload payload = JSONObject.parseObject(payloadObj.toString(), Payload.class);
        // 3.返回用户信息
        return payload;
    }

}